Introduction

Le jeu de données que nous allons étudier dans ce projet est un recueil d’informations sur des bombardements ayant eu lieu pendant de grands conflits.
Nous allons nous intéresser ici aux bombardements Alliés durant la Seconde guerre mondiale.
Le jeu de données est composé de 178281 bombardements, et 62 variables listant toutes sortes d’informations sur chaque bombardements.
Dans ce projet, nous allons nous intéresser aux pays qui ont subit ces bombardements et nous allons tenter de savoir quels sont les pays et villes qui ont été le plus touché et quels sont les pays qui ont effectué ces bombardements.
Voici la liste des variables retenus pour cette analyse :


Ce jeu de données est disponible sur le site data.world et en voici un lien : https://data.world/datamil/world-war-ii-thor-data

Importation des library

library(dplyr)
library(rnaturalearth)
library(ggplot2)
library(gganimate)
library(stringr)
library(readxl)
library(maptools)
library(sf)
library(cartogram)
library(viridis)
library(readr)
library(cowplot)
library(wordcloud)

Importation des données

WW2 <- read.csv('THOR_WWII_DATA_CLEAN.csv',na = '',sep=',',header=T)

WW2 %>% select(WWII_ID, MSNDATE, COUNTRY_FLYING_MISSION, TGT_COUNTRY,LATITUDE, LONGITUDE, TGT_LOCATION) -> WW2

WW2$MSNDATE <- as.Date(WW2$MSNDATE, format="%m/%d/%Y")

WW2 %>% na.omit(c(LATITUDE,LONGITUDE)) -> W2
W2 %>% na.omit(MSNDATE) -> W2

Nous effectuons une petite correction des données notamment en supprimant les lignes où la longitude et la latitude sont manquantes ainsi que les lignes où la date est manquante.

Première visualisation

world <- ne_countries(scale = "medium", returnclass = "sf")

W2 %>% filter(COUNTRY_FLYING_MISSION == c('GREAT BRITAIN','USA')) -> W2_EU

gifEU <- ggplot(world) + geom_sf(fill = "linen") + coord_sf(xlim = c(-25,50), ylim = c(35,70), expand = FALSE)
gifEU +  geom_point(aes(x = W2_EU$LONGITUDE, y = W2_EU$LATITUDE,color= COUNTRY_FLYING_MISSION),
                   size=1.3, data = W2_EU) + 
  transition_time(W2_EU$MSNDATE) +
  ggtitle('Europe bombardment by the allies',subtitle = 'Date: {frame_time}') +
  xlab("Longitude") + ylab("Latitude") +
  scale_colour_manual(values=c("coral2", "darkgoldenrod2")) + theme(legend.position="bottom") +
  guides(color = guide_legend(override.aes = list(size = 4))) + labs(color = "Attacking Country") +
  theme(legend.title = element_text(size = 16), legend.text = element_text(size = 14),
        plot.title = element_text(size = 20), plot.subtitle = element_text(size = 17), 
        axis.title.x = element_text(size = 16), axis.title.y = element_text(size = 16),
        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_rect(fill = 'aliceblue')) + shadow_mark()

Ce premier graphique nous montre sous forme d’un GIF tout les bombardements alliés effectués en Europe entre 1940 et 1945, le GIF a notamment été codé avec la fonction transition_time du package gganimate ainsi qu’avec la fonction ne_countries du package rnaturalearth.
Chaque point représente un bombardement et la couleur des points représente le pays attaquant.
On remarque qu’avant l’entrée en guerre des États-Unis, la Grande Bretagne était la seule nation qui résistait à l’Allemagne avec des bombardements en majorité au nord de l’Europe continentale.
Puis les États-Unis sont entrés en guerre à partir de fin 1941 et ont énormenent bombardé l’Italie et l’Allemagne.
On peut dire que les américains ont fait exploser le nombre de bombardements de l’Europe à partir de 1943.

W2 %>% filter(COUNTRY_FLYING_MISSION == c("AUSTRALIA",'GREAT BRITAIN',"NEW ZEALAND",'USA')) -> W2_AS

gifAS <- ggplot(world) + geom_sf(fill = "linen") + coord_sf(xlim = c(70,180), ylim = c(-45,70), expand = FALSE)
gifAS +  geom_point(aes(x = W2_AS$LONGITUDE, y = W2_AS$LATITUDE,color= COUNTRY_FLYING_MISSION),
                   size=1.4, data = W2_AS) + 
  transition_time(W2_AS$MSNDATE) +
  ggtitle('Asia bombardment by the allies',subtitle = 'Date: {frame_time}') + 
  xlab("Longitude") +  ylab("Latitude") +
  scale_colour_manual(values=c("purple","coral2","brown", "darkgoldenrod2")) +
  theme(legend.position="bottom") +
  guides(color = guide_legend(override.aes = list(size = 4))) + labs(color = "Attacking Country") +
  theme(legend.title = element_text(size = 16), legend.text = element_text(size = 14),
        plot.title = element_text(size = 20), plot.subtitle = element_text(size = 17), 
        axis.title.x = element_text(size = 16), axis.title.y = element_text(size = 16),
        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_rect(fill = 'aliceblue')) + shadow_mark()

Ce deuxième graphique est exactement similaire au premier en terme de codage, mais cette fois ci on voit le bombardement de l’Asie durant la guerre et on voit directement que c’est les États-Unis qui ont le plus bombardé de ce coté du globe.
Beaucoup de pays asiatiques ont été touché dont l’Indonésie, la Birmanie, les Philippines ou encore le Japon.

Remarque : le jeu de données contient notamment des informations sur les deux bombardements nucléaires d’Hiroshima et de Nagazaki on voit par exemple que la bombe Little Boy largée sur Hiroshima avait une puissance équivalente à 15000 tonnes de TNT.

Deuxième visualisation

data <- read_excel('bombardements_EU.xlsx',col_names = T,skip=1)

countriesEU = c('Albania','Austria', 'Belgium','Bosnia and Herzegovina','Bulgaria',
                'Cyprus', 'Czech Republic','Denmark','France','Germany','Greece',
                'Hungary','Italy','Luxembourg','Montenegro','Netherlands','Poland','Romania','Switzerland')
#countriesAS <- c("Burma","Cambodia","China","India","Indonesia","Iraq","Japan","Kiribati",
#               "Korea, Democratic People's Republic of","Korea, Republic of","Malaysia",
#               "Papua New Guinea","Philippines","Thailand","Timor-Leste")

mapsEU = wrld_simpl[wrld_simpl$NAME %in% countriesEU,] #mapsAS <- wrld_simpl[wrld_simpl$NAME %in% countriesAS,]

EUROPE <- st_as_sf(mapsEU) ; st_EUROPE <- st_transform(EUROPE, crs = 3395) ;st_EUROPE <- left_join(st_EUROPE,data)
#ASIA <- st_as_sf(mapsAS) ; st_ASIA <- st_transform(ASIA, crs = 3395) ; st_ASIA <- left_join(st_ASIA,data2)

cartogram_EU <- cartogram_cont(st_EUROPE, "n",itermax = 18) ; cartogram_EU2 <- cartogram_cont(st_EUROPE, "n",itermax = 0)
#cartogram_ASIA <- cartogram_cont(st_ASIA, "n",itermax = 8) ; cartogram_ASIA2 <- cartogram_cont(st_ASIA, "n",itermax = 0)

cartogram_EU_3P <- cartogram_EU[cartogram_EU$NAME %in% c('France','Germany','Italy'),]
#cartogram_AS_6P <- cartogram_ASIA[cartogram_ASIA$NAME %in% c('Burma','China','Indonesia','Japan','Papua New Guinea','Philippines'),]

g1 <- ggplot() + geom_sf(data = cartogram_EU, aes(fill = n)) + #data = cartogram_AS
  scale_fill_viridis(direction= 1,breaks=c(1,100,5000,10000, 20000, 30000), #breaks=c(1,100,5000,7000,10000)
                     option = 'viridis',name="Number of bombardments",
                     guide = guide_legend( keyheight = unit(4, units = "mm"), keywidth = unit(6, units = "mm"), 
                                           label.position = "bottom", title.position = 'top', nrow=1)) +
  theme_void() + labs( title = "After" ) +
  theme(text = element_text(size = 18,color = "#22211d"), 
        plot.background = element_rect(fill = "gray97", color = NA), panel.background = element_rect(fill = "gray97", color = NA), 
        legend.background = element_rect(fill = "gray97", color = NA), plot.title = element_text(size= 22, hjust=0.5, color = "gray25"),
        legend.position = c(-0.02, 0.90), legend.title = element_text(size = 17), legend.text = element_text(size = 10)) +
  geom_sf_text(cartogram_EU_3P,mapping=aes(label = NAME), color = c('gray91','midnightblue','maroon4'),lwd=6.5) #geom_sf_text(cartogram_AS_6P...)

g2 <- ggplot() + geom_sf(data = cartogram_EU2, aes(fill = n)) +  #geom_sf(data = cartogram_ASIA2...)
  scale_fill_viridis(direction= 1,breaks=c(1,100,5000,10000, 20000, 30000), #breaks=c(1,100,5000,7000,10000)
                     option = 'viridis',name="Numbers of bombardments",
                     guide = guide_legend( keyheight = unit(4, units = "mm"), keywidth = unit(6, units = "mm"), 
                                           label.position = "bottom", title.position = 'top', nrow=1)) +
  theme_void() + labs( title = "Before" ) +
  theme(text = element_text(size = 18,color = "#22211d"), 
        plot.background = element_rect(fill = "gray97", color = NA), panel.background = element_rect(fill = "gray97", color = NA), 
        legend.background = element_rect(fill = "gray97", color = NA), plot.title = element_text(size= 22, hjust=0.5, color = "gray25"),
        legend.position = c(0.81, 0.88)) +
  theme(legend.position = "none") +
  geom_sf_text(cartogram_EU_3P,mapping=aes(label = NAME), color = c('gray91','midnightblue','maroon4'),lwd=5) #geom_sf_text(cartogram_AS_6P...)

plot_grid(g2,g1,g4,g3,align = 'h',labels=c("Europe countries superficy depending on bombardment","","Asia countries superficy depending on bombardment",""),label_size = 23,vjust = c(1.1,0,1.1,0),hjust = c(-0.4,0,-0.4,0))

Le codage de ces graphiques à nécéssité des fonctions de plusieurs packages : sf, maptools, cartogram et cowplot.
Le fichier html ne présente que l’un des deux codes, celui de l’Europe.
Le code pour l’Asie est similaire, alors pour ne pas alourdir la taille du fichier html, les lignes de codes pour l’Asie ont été misent en commentaires car seules quelques lignes diffèrent entre les deux codes.
Par ailleurs, un nouveau jeu de données à été nécéssaire pour coder ces graphiques.
C’est un jeu de données que j’ai crée moi même listant les pays bombardés, leur contient, leur latitude et longitude ainsi que le nombre de bombardements subit, voici le lien vers ce jeu données : lien

La première colonne des graphiques nous montre tout les pays européens et asiatiques présents dans le jeu de données avec pour chaque couleur un nombre de bombardements subit.
On voit que du côté européen c’est l’Allemagne qui à le plus subit et du côté asiatique/océanie c’est la Papouasie-Nouvelle Guinée.
On se demande ensuite à quoi ressemblerait la superficie des pays si elle était proportionnelle au nombre de bombardements subit, c’est ce que nous voyons dans la deuxième colonne des graphiques.
Cela nous permet d’avoir une visualisation exagérée mais très pertinante car cela nous permet en plus des couleurs de beaucoup mieux voir les différences entre certains pays.

Troisième visualisation

WW2 %>% count(TGT_LOCATION) -> TGT_LOCATION_count

TGT_LOCATION_count %>% na.omit() -> TGT_LOCATION_count

`%!in%` <- Negate(`%in%`)
TGT_LOCATION_count %>% filter(TGT_LOCATION %!in% c("UNIDENTIFIED","UNKNOWN","45 00 N 010 40 E","CITY TOT UNDER 6 TON",
                                                  "44 40 N 006 20 E","44 40 N 010 20 E"," 45 00 N 011 00 E",
                                                  "45 00 N 009 40 E","44 40 N 011 20 E","45 20 N 010 40 E",
                                                  "44 40 N 011 00 E","45 00 N 011 00 E")) -> TGT_LOCATION_count

TGT_LOCATION_count$TGT_LOCATION <- str_to_lower(TGT_LOCATION_count$TGT_LOCATION)
TGT_LOCATION_count$TGT_LOCATION <- str_to_title(TGT_LOCATION_count$TGT_LOCATION)

wordcloud(words = TGT_LOCATION_count$TGT_LOCATION,
          freq = TGT_LOCATION_count$n,
          min.freq = 1,
          max.words=200, 
          colors=brewer.pal(8, "Dark2"),
          random.order = FALSE,
          rot.per=0.1,
          scale = c(5,0.2))

Le codage de ce graphique à nécéssité la fonction wordcloud du package wordcloud.
Dans ce graphique, on essaye d’être encore plus précis en affichant les villes les plus bombardées.
Puis le nom de la ville est grande, plus elle s’est faite bombardée.
On voit sans surprise que c’est les villes allemandes qui ont le plus subit, Berlin en numéro un puis, les villes de Hambourg, Brème ou encore Cologne.
Cette visualisation nous permet de voir encore plus en détails les cibles des bombardements alliées.

Conclusion

Ce jeu de données est très interessant car il est riche en variables, on peut donc faire une multitude de visualisation différentes.
L’inconvénient est que certaines variables présentent trop de valeurs manquantes donc risque de biaiser les résultats et l’interprétation des graphiques.

Bonus : Reproduction du graphique d’Étienne-Jules Marey, trajets et horaires des trains entre Paris et Lyon (1885).

Train <- read_excel('coord.xlsx',col_names = F,skip=1)
Train <- Train[-1,]
colnames(Train) <- c('x0','y0','x1','y1','no_trajet','section','id','horaires','ville_depart','ville_arrivee','Année')
as_tibble(Train) -> Train
Train %>% mutate(x0=parse_number(x0),y0=parse_number(y0),x1=parse_number(x1),
               y1=parse_number(y1),no_trajet=parse_number(no_trajet),
               section=parse_number(section),id=parse_number(id)) -> Train

x <- 1 ; y <- 1
plot(x,y,axes=FALSE,xlim=c(0,24),ylim=c(0,20),col='white',xlab = "",ylab = "")
segments(seq(0,24,1/6),rep(1,length(seq(0,24,1/6))),
               seq(0,24,1/6),rep(20,length(seq(0,24,1/6))),
               lty=1,col='gray65')
      
segments(24,1,24,20,lty=1,col='black')
      
axis(1,at=c(0:24),labels=c("6","7","8","9","10","11","midi","1","2","3","4","5","6","7",
                                 "8","9","10","11","minuit","1","2","3","4","5","6"),pos=1)
axis(3,at=c(0:24),labels=c("6","7","8","9","10","11","midi","1","2","3","4","5","6","7",
                                 "8","9","10","11","minuit","1","2","3","4","5","6"),pos=20)
axis(2,at=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20),
     labels=c("LYON","","","","","","","","","","Nuits",
              "","","Laroche","","","Montereau","","","PARIS"),las=1,pos=0)
axis(2,at=c(1.75,3.5,5.5,6.25,7.75,9.75,12.25,17.5),
     labels=c("St germain","Macon","Chalons","Chagny",
              "Dijon","Les Laumes","Tonnerre","Moret"),las=1,pos=0)
      
segments(rep(0,11),c(1.75,3.5,5.5,6.25,7.75,9.75,11,12.25,14,17,17.5),
         rep(24,11),c(1.75,3.5,5.5,6.25,7.75,9.75,11,12.25,14,17,17.5),lty=1,col='black')

Train1 <- Train[Train$Année == 1885,] #Train2 <- Train[Train$Année == 2022,]
segments(Train1$x0, Train1$y0, Train1$x1, Train1$y1, lty = 1) #segments(Train2$x0, Train2$y0, Train2$x1, Train2$y1, lty = 1)

En bonus, j’ai décidé de reproduire la carte d’Étienne-Jules Marey sur les trajets de train entre Paris et Lyon en 1885.
J’ai décidé de reproduire cette carte en traçant des segments qui réprésentent les trajets, il m’a donc fallu des coordonnées de départ et d’arrivée pour chacun de ces segments.
J’ai crée moi même un jeu de données qui répertorie les variables suivantes :

  • x0, y0, x1 et y1 qui sont les coordonnées de chaque trajet sur le graphique.
  • no_traj qui est un numéro unique pour chaque trajet.
  • section qui représente l’emplacement entre les villes pour chaque trajet.
  • id qui est un nuémro unique pour chaque segments.
  • horaires qui est l’horaire de chaque début de trajet par tranches de deux heures.
  • ville_depart qui est la ville de départ du trajet.
  • ville_arrivee qui est la ville d’arrivée du trajet.
  • Année qui est l’année du trajet (1885 ou 2022).


Voici un lien vers ce jeu de données : lien

Trajets entre Paris et Lyon (2022)

Les codes de ce graphique ne sont pas affichés dans le fichier html car il n’y a que deux lignes de code qui diffèrent avec le précédent, elles sont en commentaires du code précédent.
J’ai décidé de revisiter ce graphique en traçant les horaires des TGV entre Paris et Lyon en 2022.
J’ai directement récupéré les données sur le site de la SNCF et je les ai ajouté au jeu de données précédent.
On voit l’énorme diminution du temps de trajet entre 1885 et 2022, aujourd’hui le temps de trajet entre Paris et Lyon est d’environ 2h.

Pour finir j’ai codé une application Rshiny où vous pouvez selectionner une ville et un horaire de départ et l’application vous renvoyer les trajets correspondants.
Voici un lien vers l’application : https://idirsadaoui.shinyapps.io/Horaires_Trains/